مشخصات مقاله
-
3235
-
0.0
-
10408
-
0
-
0
آموزش استفاده از Drawable ها در اندروید
دوره آموزش برنامه نویسی اندروید
کلیه حقوق مادی و معنوی این مقاله متعلق به آموزشگاه تحلیل داده می باشد و هر گونه استفاده غیر قانونی از آن پیگرد قانونی دارد.
در این بخش به کاربرد drawable ها در اندروید می پردازیم.
فهرست محتوا
1. Drawable چیست؟
2. استفاده از drawable ویژه ی view ها
3. بار گذاری Bitmap ها و drawable ها
4. XML Drawables
Shape Drawable چیست؟
State Drawable چه کاربردی دارد؟
آموزش Transition Drawable
5. تعریف Vector drawable
6. معرفی Animation Drawable
7. Patch Drawable چیست؟
8. ایجاد Drawable های سفارشی
9. تمرین ایجاد Drawable های سفارشی
1. Drawable چیست؟
منبع Drawable در واقع یک مفهوم کلی برای نگاره ای است که می توان رسم کرد. ساده ترین شکل آن یک فایل نگاره ای bitmap است، که در اندروید توسط کلاس BitmapDrawable نمایش داده می شود.
هر Drawable به عنوان فایل های جدا در یکی از پوشه های res/drawable ذخیره و نگه داری می شوند. bitmap ها ویژه ی وضوح تصویرهای متفاوت در زیرپوشه های –mdpi، -hdpi، -xhdpi، -xxhdpi پوشه ی والد res/drawable ذخیره می شوند. راهنمای ایجاد پروژه ی ابزار برنامه نویسی اندروید (ADT project creation wizard) این پوشه ها را خود به صورت پیش فرض ایجاد می کند. اگر نقشه های بیتی مذکور در پوشه های متفاوت نگه داری شوند، سیستم اندروید خود به صورت خودکار نقشه ی بیتی مورد نظر را بر اساس پیکربندی دستگاه (device config) انتخاب می کند.
چنانچه مختص تمامی وضوح تصویرهای موجود نقشه ی بیتی در نظر نگرفته باشید، سیستم اندروید نقشه ی بیتی با نزدیکترین مقیاس به آن وضوح تصویر را با کمی تنظیم انتخاب می کند. البته این امر نتیجه ی چندان دلخواهی ارائه نمی دهد، به این خاطر که نقشه ی بیتی حاصل ممکن است تا حدی کم کیفیت و تار شود.
علاوه بر فایل های گرافیکی، اندروید از XML drawables و نگاره های 9-patch نیز پشتیبانی می کند.XML drawables بیشتر جهت تعریف اشکال (رنگ، گرادیان، حاشیه) وضعیت، transition ها مورد استفاده قرار می گیرد.
9-patch graphics زمانی به کار می رود که نگاره (graphic) لازم است به دلیل بزرگتر بودن view دربرگیرنده ی آن، بسط داده و کشیده (stretch) شود، 9-patch graphics در حقیقت تعیین می کند کدام بخش از نگاره باید متناسب با view مورد نظر بسط داده شود.
این امکان نیز وجود دارد که Drawable ها را در کد جاوا نوشت. هر شی که Drawable پیاده سازی می کند می توان به عنوان Drawable in code مورد استفاده قرار داد.
2. استفاده از drawable ویژه ی view ها
برای ارجاع به Drawable ها در XML باید از طریق @drawable/filename ترتیب عمل داد. برای این منظور اسم فایل را بدون پسوند فایل مورد استفاده قرار می دهیم، به عنوان مثال اگر بخواهیم به res/drawable/hello.png دسترسی پیدا کنیم، @drawable/hello را بکار می بریم (به عبارت دیگر پسوند .png را از انتهای آن حذف می کنیم). توجه خود را به مثال زیر جلب کنید.
<textview xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/hello"
android:text="@string/hello_world" />
همچنین این قابلیت وجود دارد که Drawable ها را (داخل کد) به View ها تخصیص داد. گفتنی است بیشتر view ها یک شناسه ی منبع (resource ID) به مثابه ی پارامتر ورودی (input parameter) می پذیرند. برای مثال نمونه کد زیر نحوه ی متصل یا سِت کردن drawables به عنوان پس زمینه به ImageView را نمایش می دهد.
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageResource(R.drawable.hello);
3. بار گذاری Bitmap ها و drawable ها
اندروید جهت کار با نقشه های بیتی، کلاس Bitmap را ارائه می دهد. این بخش به تشریح نحوه ی ایجاد اشیا Bitmap با استفاده از کد جاوا پرداخته، همچنین نحوه ی تبدیل اشیا Bitmap به اشیا Drawable و بالعکس را به شما آموزش می دهد.
در صورت نیاز می توان هر bitmap file قابل دسترسی در کد را بارگذاری کرده، سپس آن را به شی Drawable تبدیل کرد.
نمونه کد زیر نحوه ی ایجاد شی Bitmap ویژه ی پوشه ی assets و تخصیص آن به ImageView را نمایش می دهد.
// Get the AssetManager
AssetManager manager = getAssets();
// read a Bitmap from Assets
InputStream open = null;
try {
open = manager.open("logo.png");
Bitmap bitmap = BitmapFactory.decodeStream(open);
// Assign the bitmap to an ImageView in this layout
ImageView view = (ImageView) findViewById(R.id.imageView1);
view.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (open != null) {
try {
open.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
همچنین می توان از پوشه ی res/drawable به Drawable ها دسترسی پیدا کرد و آن ها را به عنوان اشیا Bitmap در متن برنامه (source code) بکار برد. مثال زیر این امر را به نمایش می گذارد.
Bitmap b = BitmapFactory.decodeResource(getResources()، R.drawable.ic_action_search);
می توانید یک مقیاس نقشه ی بیتی (scale bitmap) بر اساس تعریف جدیدی از درازا (height) و پهنا (weight) بر حسب پیکسل ایجاد کنید.
Bitmap originalBitmap = <initial setup>;
Bitmap resizedBitmap =
Bitmap.createScaledBitmap(originalBitmap، newWidth، newHeight، false);
به منظور تبدیل یک شی Bitmap به Drawable می توان از کد زیر بهره گرفت.
# Convert Bitmap to Drawable
Drawable d = new BitmapDrawable(getResources()،bitmap);
4. XML Drawables
Shape Drawable چیست ؟
Shape Drawables فایل های XML ای هستند که به برنامه نویس اجازه می دهد یک شی هندسی همراه با رنگ ها، حاشیه ها و گرادیان ها (gradiant) ترسیم کرده، سپس آن را به Views اختصاص دهد. فایده استفاده از drawable گفته شده در توانایی تطبیق آن به صورت خودکار با اندازه مناسب و تعریف شده است.
کد زیر مثالی از این نوع drawable عرضه می کند.
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="2dp"
android:color="#FFFFFFFF" />
<gradient android:endcolor="#DDBBBBBB"
android:startcolor="#DD777777"
android:angle="90" />
<corners android:bottomrightradius="7dp"
android:bottomleftradius="7dp"
android:topleftradius="7dp"
android:toprightradius="7dp" />
</shape>
می توانید در صورت تمایل drawable نام برده را به خصوصیت پس زمینه (background property) طرح بندی (layout) خود تخصیص دهید.
<?xml version="1.0" encoding="utf-8" ?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/myshape"
android:orientation="vertical">
<edittext android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</edittext>
<radiogroup android:id="@+id/radioGroup1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<radiobutton android:id="@+id/radio0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/celsius">
</radiobutton>
<radiobutton android:id="@+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fahrenheit">
</radiobutton>
</radiogroup>
<button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/calc"
android:onclick="myClickHandler"></button>
</linearlayout>
State Drawable چه کاربردی دارد؟
State drawable امکان تعریف وضعیت (state) را برای برنامه نویس فراهم می کند. لازم به ذکر است که ویژه ی هر وضعیت (state) یک drawable جدا به View مربوط تخصیص می یابد. به عنوان نمونه، کد زیر برای یک دکمه بسته به وضعیت های مختلفی که دارد یک drawable یکتا تعریف می کند.
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_pressed"
android:state_pressed="true" />
<item android:drawable="@drawable/button_checked"
android:state_checked="true" />
<item android:drawable="@drawable/button_default" />
</selector>
آموزش Transition Drawable
Transition Drawables برای شما این امکان را فراهم می کند که افکت transition را تعریف کرده و در کدنویسی آن را فعال سازی کنید.
<?xml version="1.0" encoding="utf-8" ?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/first_image" />
<item android:drawable="@drawable/second_image" />
</transition>
final ImageView image = (ImageView) findViewById(R.id.image);
final ToggleButton button = (ToggleButton) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
TransitionDrawable drawable = (TransitionDrawable) image.getDrawable();
if (button.isChecked()) {
drawable.startTransition(500);
} else {
drawable.reverseTransition(500);
}
}
});
5. تعریف Vector drawables
ویرایش 5.0 اندروید، قابلیت تعریف vector drawable را مشابه فایل های svg (اما با گستره ای به نسبت محدودتر) در اختیار برنامه نویس قرار می دهد. لیستینگ زیر کاربرد drawable ذکر شده را در فایل vectordrawable.xml با مثال نمایش می دهد. استفاده از vector drawable این مزیت را دارد که مقیاس drawable را متناسب با چگالی دستگاه (device density) به صورت خودکار تنظیم می کند.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="64dp"
android:width="64dp"
android:viewportheight="600"
android:viewportwidth="600">
<group
android:name="rotationGroup"
android:pivotx="300.0"
android:pivoty="300.0"
android:rotation="45.0">
<path
android:name="v"
android:fillcolor="#000000"
android:pathdata="M300،70 l 0،-70 70،70 0،0 -70،70z" />
</group>
</vector>
نسخه ی 5.0 اندروید همچنین دربردارنده ی AnimatedVectorDrawable است که به شما اجازه می دهد vector drawable ها را با animation ها ترکیب کنید.
6. معرفی Animation Drawables
همچنین می توان یک animation drawable تعریف کرده و آن را با فراخوانی متد setBackgroundResource() به View تخصیص داد.
<!-- Animation frames are phase*.png files inside the
res/drawable/ folder -->
<animation-list android:id="@+id/selected" android:oneshot="false">
<item android:drawable="@drawable/phase1" android:duration="400" />
<item android:drawable="@drawable/phase2" android:duration="400" />
<item android:drawable="@drawable/phase3" android:duration="400" />
</animation-list>
ImageView img = (ImageView)findViewById(R.id.yourid);
img.setBackgroundResource(R.drawable.your_animation_file);
// Get the AnimationDrawable object.
AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();
// Start the animation (looped playback by default).
frameAnimation.start();
7. Patch Drawable چیست؟
یک نقشه ی بیتی قابل اندازه بندی مجدد می باشد که دارای نواحی قابل بسط (stretchable) بوده و به برنامه نویس این اجازه را می دهد که آن نواحی (قابل بسط) را تعریف کند. در قسمت فوقانی و چپ، ناحیه را تعیین می کنید که باید در صورت کوچک بودن drawable برای view تنظیم مقیاس شود. نواحی قابل بسط را در تصویر زیر مشاهده می کنید.
در قسمت پایین و راست نیز ناحیه ای را تعریف می کنیم که متن در آن قرار می گیرد، به عبارتی دیگر این امر زمانی رخ می دهد که Drawable در view ی بکار رفته که می توان روی آن متن نوشت (به عنوان مثال می توان به یک دکمه اشاره کرد).
مجموعه ابزار برنامه نویسی اندروید (ADT) برنامه ی draw9patch را در پوشه ی نصب android-sdk/tools برای برنامه نویس در نظر گرفته است. برنامه ی پروسه ی ایجاد 9 Patch drawables را تا حد قابل توجهی آسان می کند.
8. ایجاد Drawable های سفارشی
می توان در صورت نیاز Drawable های سفارشی تعریف کرد. Drawable های اختصاصی قادر هستند برای نمایش از رابط برنامه سازی کاربردی Canvas کمک گرفته و بدین وسیله متناسب با نیاز شما تنظیم شوند.
9. تمرین ایجاد Drawable های سفارشی
پروژه ی زیر به نام com.vogella.android.drawables.custom را که مبتنی بر قالب Empty Activity است را ایجاد کنید.
حال کلاس سفارشی Drawable (زیر) را ایجاد کنید.
package com.vogella.android.drawables.custom;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
public class MyRoundCornerDrawable extends Drawable {
private Paint paint;
public MyRoundCornerDrawable(Bitmap bitmap) {
BitmapShader shader;
shader = new BitmapShader(bitmap، Shader.TileMode.CLAMP،
Shader.TileMode.CLAMP);
paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
}
@Override
public void draw(Canvas canvas) {
int height = getBounds().height();
int width = getBounds().width();
RectF rect = new RectF(0.0f، 0.0f، width، height);
canvas.drawRoundRect(rect، 30، 30، paint);
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
اکنون جهت استفاده از کلاس بالا، فایل layout خود را به زیر تغییر دهید.
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<imageview
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerhorizontal="true"
android:layout_centervertical="true"
android:contentdescription="TODO" />
</relativelayout>
کلاس MainActivity را به کلاس زیر درست کنید. این کد نیاز دارد شما یک نقشه ی بیتی در پوشه ی drawable خود به نام dog.png ایجاد کنید.
package com.vogella.android.drawables.custom;
import java.io.InputStream;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ImageView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView button = (ImageView) findViewById(R.id.image);
InputStream resource = getResources().openRawResource(R.drawable.dog);
Bitmap bitmap = BitmapFactory.decodeStream(resource);
button.setBackground(new MyRoundCornerDrawable(bitmap));
}
}
